/*
 * @Author: pengtianrui 2276608413@qq.com
 * @Date: 2024-07-19 14:42:56
 * @LastEditors: 武兴创 superjava@vip.qq.com
 * @LastEditTime: 2024-08-28 17:46:42
 * @FilePath: \SGFEM\DataStructure\FEM\Constraint\include\MPCData.h
 * @Description: MPC定义， 可以用于表示齐次多点约束方程。也可以用来表示非齐次多点约束方程
 * MPC
 */

#pragma once

#include "DataStructure/Common/DataStructureNamespace.h"
#include "DataStructure/Common/Id.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Common/SetBase.h"
#include "DataStructure/Input/Solver/DOFDirections.h"

SG_DATASTRUCTURE_FEM_NAMESPACE_OPEN
struct DECLSPEC MPCData : public SetBase
{
    struct DECLSPEC MPCComponent
    {
        SG::DataStructure::Common::Id   m_nodeId = 0;    //< 节点id
        SG::DataStructure::Common::I64  m_dof    = 0;    //< 参与约束方程的自由度方向
        SG::DataStructure::Common::Real m_factor = 0.0;  //< 方程系数

        SG::DataStructure::FEM::DofSet GetDofs () const
        {
            return Int2VDofSet (m_dof);
        }
    };

    MPCComponent m_slaveItem;  //< 方程中被约束项， 本项系数必须为非零值
    // SG::DataStructure::Common::Real m_Y;      //< 约束方程中的非齐次项
    SG::DataStructure::Common::Id m_domainId = 0;
    std::vector<MPCComponent>     m_masterItems;

    /** @brief 设置方程中从节点相关项 */
    void SetSlaveItem (const SG::DataStructure::Common::Id&         node,
                       const SG::DataStructure::FEM::DOFDirections& dof,
                       const SG::DataStructure::Common::Real&       factor);

    /** @brief 添加主节点有关项 */
    void AddMasterItem (const SG::DataStructure::Common::Id&         node,
                        const SG::DataStructure::FEM::DOFDirections& dof,
                        const SG::DataStructure::Common::Real&       factor);

    /** @brief  设置非齐次项系数 */
    // void SetInhomogeneousFactor (const SG::DataStructure::Common::Real Y);
};

/// @brief p判断两个MPCComponent是否相等
/// @param lhs
/// @param rhs
/// @return
DECLSPEC bool operator== (const MPCData::MPCComponent& lhs, const MPCData::MPCComponent& rhs);

/// @brief 判断两个MPCData是否相等
/// @param lhs
/// @param rhs
/// @return
DECLSPEC bool operator== (const MPCData& lhs, const MPCData& rhs);

/// @brief 比较两个MPCData大小
/// @param lhs
/// @param rhs
/// @return
DECLSPEC bool operator< (const MPCData& SGDataA, const MPCData& SGDataB);

SG_DATASTRUCTURE_FEM_NAMESPACE_CLOSE